package com.sxj.PDMS.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sxj.PDMS.common.ErrorCode;
import com.sxj.PDMS.exception.BusinessException;
import com.sxj.PDMS.mapper.*;
import com.sxj.PDMS.model.entity.*;
import com.sxj.PDMS.model.dto.student.StudentSelectRequest;
import com.sxj.PDMS.model.vo.PagingQueryResponse;
import com.sxj.PDMS.service.StudentManageService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

import static com.sxj.PDMS.utils.VerifyUtil.*;

@Service
@Slf4j
public class StudentManageServiceImpl implements StudentManageService {
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private StudentManageMapper studentManageMapper;
    public static final String SALT = "tyutrjxy";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registerStudentBatch(List<Student> students) {
        log.info("批量注册学生");
        students.forEach(student -> {
            // 1. 校验
            if (StringUtils.isAnyBlank(student.getName(),
                    student.getStudentNumber(), student.getIdNumber(),
                    student.getGrade(), student.getGender(),
                    student.getFullHomeAddress(), student.getLiveInTheDormitory(),
                    student.getNation(), student.getNativePlace(),
                    student.getPhoneNumber(), student.getThePartyBranch())
                    && student.getDateOfBirth() == null
            ) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
            }
            if (student.getStudentNumber().length() != 10) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的学号有误");
            }
//            if (student.getStudentNumber().length() > 18) {
//                throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的用户账号过长");
//            }
            if (!isValidChinesePhoneNumber(student.getPhoneNumber())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的电话格式错误");
            }
            if (!isValidChineseID(student.getIdNumber())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的身份证号格式错误");
            }
            if (!isValidEmail(student.getEmail())) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的邮箱格式错误");
            }


            synchronized (student.getStudentNumber().intern()) {
                // 账户不能重复
                QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("student_number", student.getStudentNumber());

                long count = studentMapper.selectCount(queryWrapper);

                if (count > 0) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, student.getStudentNumber() + "的账号已存在");
                }
                // 2. 加密
                // todo 修改加密方式
                String encryptPassword = DigestUtils.md5DigestAsHex((SALT + student.getPassword()).getBytes());
                // 3. 插入数据
                Student newStudent = new Student();

                BeanUtils.copyProperties(student, newStudent);
                student.setPassword(encryptPassword);

                int inserted = studentMapper.insert(student);
                if (inserted < 0) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
                }
            }
        });
    }

    @Override
    public PagingQueryResponse<Student> selectAll(Integer page, Integer pageSize) {

        Integer start = (page - 1) * pageSize;
        List<Student> students = studentManageMapper.selectAll(start, pageSize);
        Long total = studentManageMapper.selectTotal();

        PagingQueryResponse<Student> pagingQueryResponse = new PagingQueryResponse<>();
        pagingQueryResponse.setRows(students);
        pagingQueryResponse.setTotal(total);

        return pagingQueryResponse;

    }

    @Override
    public PagingQueryResponse<Student> selectWithCondition(Integer page,
                                                            Integer pageSize,
                                                            StudentSelectRequest studentSelectRequest
    ) {
        Integer start = (page - 1) * pageSize;

        String studentNumber = studentSelectRequest.getStudentNumber();
        String name = studentSelectRequest.getName();
        String gender = studentSelectRequest.getGender();
        String grade = studentSelectRequest.getGrade();
        String classNum = studentSelectRequest.getGrade();
        Integer status = studentSelectRequest.getStatue();
        String thePartyBranch = studentSelectRequest.getThePartyBranch();

        List<Student> students = studentManageMapper.selectWithCondition(start, pageSize, studentNumber, grade, classNum, name, gender, status, thePartyBranch);
        Long total = studentManageMapper.selectWithConditionTotal(studentNumber, grade, classNum, name, gender, status, thePartyBranch);

        PagingQueryResponse<Student> pagingQueryResponse = new PagingQueryResponse<>();
        pagingQueryResponse.setRows(students);
        pagingQueryResponse.setTotal(total);

        return pagingQueryResponse;
    }

    //todo 乱码问题
    @Override
    public void selectAllStudentAndDownload(StudentSelectRequest studentSelectRequest, HttpServletResponse response) {
        String studentNumber = studentSelectRequest.getStudentNumber();
        String name = studentSelectRequest.getName();
        String gender = studentSelectRequest.getGender();
        String grade = studentSelectRequest.getGrade();
        String classNum = studentSelectRequest.getGrade();
        Integer status = studentSelectRequest.getStatue();
        String thePartyBranch = studentSelectRequest.getThePartyBranch();


        // 1. 查询数据
        List<Student> students = studentManageMapper.selectWithConditionAndDownload(studentNumber, grade, classNum, name, gender, status, thePartyBranch);

        if (students == null || students.isEmpty()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有符合条件的学生");
        }

        // 2.通过POI将数据写入template/学生基本信息表.xlsx文件
        InputStream stream = this.getClass().getClassLoader().getResourceAsStream("template/学生基本信息表.xlsx");
        try {
            XSSFWorkbook excel = new XSSFWorkbook(stream);

            // 填充数据
            for (int i = 0; i < students.size(); i++) {
                XSSFSheet sheet = excel.getSheetAt(0);
                // 获取第i+1行
                XSSFRow row = sheet.createRow(i + 2);
                Student student = students.get(i);
                row.createCell(0).setCellValue(student.getStudentNumber());
                row.createCell(1).setCellValue(student.getName());
                row.createCell(2).setCellValue(student.getGender());
                row.createCell(3).setCellValue(student.getStatue());
                row.createCell(4).setCellValue(student.getNation());
                row.createCell(5).setCellValue(student.getIdNumber());
                row.createCell(6).setCellValue(student.getGrade());
                row.createCell(7).setCellValue(student.getNativePlace());
                row.createCell(8).setCellValue(student.getFullHomeAddress());
                row.createCell(9).setCellValue(student.getPhoneNumber());
                row.createCell(10).setCellValue(student.getThePartyBranch());
                row.createCell(11).setCellValue(student.getLiveInTheDormitory());
                row.createCell(12).setCellValue(student.getEmail());
                row.createCell(13).setCellValue(student.getDateOfBirth());
                row.createCell(14).setCellValue(student.getEducationLevel());
                row.createCell(15).setCellValue(student.getEnrollmentTime());
                row.createCell(16).setCellValue(student.getIsFailingClass());
                row.createCell(17).setCellValue(student.getPreviousCredit());
                row.createCell(18).setCellValue(student.getPosition());
            }

            XSSFSheet sheet = excel.getSheetAt(0);
            XSSFRow row = sheet.createRow(students.size() + 2);
            row.createCell(0).setCellValue("下载时间:" + new Date().toString());


            // 3.通过输出流将文件下载到浏览器
            ServletOutputStream outputStream = response.getOutputStream();

            excel.write(outputStream);

            // 4.关闭资源
            excel.close();
            outputStream.close();

            log.info("学生基本信息表.xlsx下载成功");

        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件下载失败");
        }

    }
}
